# -*- coding: utf-8 -*-
"""
Qmt_查询帐户持仓信息.py
功能：查询QMT账户的持仓信息，包括持仓明细和持仓汇总
作者：Craft
日期：2025/9/2
"""
import sys
import time
import pandas as pd
from xtquant.xttrader import XtQuantTrader  # 创建交易对象使用
from xtquant.xttype import StockAccount  # 订阅账户信息使用
from xtquant import xtconstant  # 执行交易的时候需要引入
from datetime import datetime  # 时间戳改为日期时间格式的时候使用

# 设置QMT路径和账号
# 请修改为你自己的QMT安装路径和账号
path = r'D:\Program Files\证券类\国金QMT交易端模拟\userdata_mini'
acct = "246565"  # 请修改为你的账号
#acc = StockAccount('2000128', 'STOCK')
account = StockAccount(acct,'FUTURE')

def init_trader():
    """初始化交易环境"""
    # 创建交易对象
    session_id = int(time.time())
    xt_trader = XtQuantTrader(path, session_id)
    
    # 连接QMT终端
    xt_trader.start()
    if xt_trader.connect() == 0:
        print('【软件终端连接成功！】')
    else:
        print('【软件终端连接失败！】', '\n 请运行并登录miniQMT.EXE终端。', '\n path=改成你的QMT安装路径')
        return None
    
    # 订阅账户信息
    #account = StockAccount(acct,'FUTURE')
    subscribe_result = xt_trader.subscribe(account)
    if subscribe_result == 0:
        print('【账户信息订阅成功！】')
        return xt_trader, account
    else:
        print('【账户信息订阅失败！】', '\n 请检查账号是否正确。', '\n acct=""内填加你的账号')
        return None
    
    return xt_trader, ID

def query_account_info(xt_trader, ID):
    """查询账户资产信息"""
    asset = xt_trader.query_stock_asset(ID)
    print('-'*18, f'【{asset.account_id}】', '-'*18)
    if asset:
        print(f"资产总额: {asset.total_asset}\n"
              f"持仓市值: {asset.market_value}\n"
              f"可用资金: {asset.cash}\n"
              f"在途资金: {asset.frozen_cash}")
    return asset

def query_positions(xt_trader, ID):
    """查询持仓信息并返回DataFrame"""
    positions = xt_trader.query_stock_positions(ID)
    
    if not positions:
        return pd.DataFrame()
    
    positions_data = []
    for position in positions:
        positions_data.append({
            '证券代码': position.stock_code,
            '持仓数量': position.volume,
            '可用数量': position.can_use_volume,
            '冻结数量': position.frozen_volume,
            '开仓价格': position.open_price,
            '持仓市值': position.market_value,
            '在途股份': position.on_road_volume,
            '昨日持股': position.yesterday_volume,
            '盈亏金额': position.market_value - (position.volume * position.open_price),
            '盈亏比例': ((position.market_value / (position.volume * position.open_price)) - 1) * 100 if position.volume * position.open_price > 0 else 0
        })
    
    return pd.DataFrame(positions_data)

def positions_summary(positions_df):
    """计算持仓汇总信息"""
    if positions_df.empty:
        return None
    
    summary = {
        '持仓品种数': len(positions_df),
        '总持仓市值': positions_df['持仓市值'].sum(),
        '总盈亏金额': positions_df['盈亏金额'].sum(),
        '平均盈亏比例': positions_df['盈亏比例'].mean()
    }
    return summary

def main():
    """主函数"""
    # 初始化交易环境
    init_result = init_trader()
    if not init_result:
        sys.exit(1)
    
    xt_trader, ID = init_result
    
    # 查询账户资产信息
    asset = query_account_info(xt_trader, ID)
    
    # 查询持仓信息
    positions_df = query_positions(xt_trader, ID)
    
    # 打印持仓明细
    print('-'*18, '【持仓明细】', '-'*18)
    if not positions_df.empty:
        print(positions_df)
    else:
        print("无持仓信息")
    
    # 打印持仓汇总
    summary = positions_summary(positions_df)
    if summary:
        print('-'*18, '【持仓汇总】', '-'*18)
        for key, value in summary.items():
            if key == '平均盈亏比例':
                print(f"{key}: {value:.2f}%")
            else:
                print(f"{key}: {value}")
    
    # 关闭连接
    xt_trader.stop()
    print('-'*18, '【查询完成】', '-'*18)

if __name__ == "__main__":
    main()